package logs

import (
	"context"
	"fmt"
	"io"
	"os"
	"rnet/util"
	"sync"
	"time"
)

const (
	LOGPATH = "log/"
	//FORMAT .
	FORMAT = "2006-01-02_15"
	//LineFeed 换行
	LineFeed = "\r\n"
)

var FileOpt *os.File

var Hour int

var FileSync *sync.Once

var DevLogName = "dev_log.log"

func CtxInfo(ctx context.Context,format string,opts ...interface{}) string {
	logInfo := fmt.Sprintf("%s"+format,FormatLog(ctx,"INFO"),opts)
	WriteLog(DevLogName,logInfo)
	return logInfo
}
func CtxDebug(ctx context.Context,format string,opts ...interface{}) string {
	logInfo := fmt.Sprintf("%s"+format,FormatLog(ctx,"DEBUG"),opts)
	WriteLog(DevLogName,logInfo)
	return logInfo
}
func CtxWarn(ctx context.Context,format string,opts ...interface{}) string {
	logInfo := fmt.Sprintf("%s"+format,FormatLog(ctx,"WARN"),opts)
	WriteLog(DevLogName,logInfo)
	return logInfo
}
func CtxError(ctx context.Context,format string,opts ...interface{}) string {
	logInfo := fmt.Sprintf("%s"+format,FormatLog(ctx,"ERROR"),opts)
	WriteLog(DevLogName,logInfo)
	return logInfo
}

func FormatLog(ctx context.Context,level string) string {
	nowStr := time.Now().Format(util.TIMELAYOUT)
	logId,ok := ctx.Value("LogId").(string)
	if !ok || logId == ""{
		logId = util.GetLogId()
	}
	return fmt.Sprintf("%s %s %s ",level,nowStr,logId)
}


var path = LOGPATH + time.Now().Format(FORMAT) + "/"

//WriteLog return error
func WriteLog(fileName, msg string) error {
	if !IsExist(path) {
		CreateDir(path)
	}
	var (
		err error
		f   *os.File
	)
	hour := time.Now().Hour()
	if FileOpt == nil || Hour < hour{
		var NewFileSync1 sync.Once
		FileSync = &NewFileSync1
		(*FileSync).Do(func() {
			f, err = os.OpenFile(path+fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
			FileOpt = f
			Hour = hour
		})
		var NewFileSync2 sync.Once
		FileSync = &NewFileSync2
	}
	_, err = io.WriteString(FileOpt, msg+LineFeed)
	return err
}

//CreateDir  文件夹创建
func CreateDir(path string) error {
	err := os.MkdirAll(path, os.ModePerm)
	if err != nil {
		return err
	}
	os.Chmod(path, os.ModePerm)
	return nil
}

//IsExist  判断文件夹/文件是否存在  存在返回 true
func IsExist(f string) bool {
	_, err := os.Stat(f)
	return err == nil || os.IsExist(err)
}
